<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>3.4. HTTP Authentication Adapter</title>
<link rel="stylesheet" href="dbstyle.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<link rel="start" href="index.html" title="Programmer's Reference Guide">
<link rel="up" href="zend.auth.html" title="Chapter 3. Zend_Auth">
<link rel="prev" href="zend.auth.adapter.digest.html" title="3.3. Digest Authentication">
<link rel="next" href="zend.auth.adapter.ldap.html" title="3.5. LDAP Authentication">
<link rel="chapter" href="introduction.html" title="Chapter 1. Introduction to Zend Framework">
<link rel="chapter" href="zend.acl.html" title="Chapter 2. Zend_Acl">
<link rel="chapter" href="zend.auth.html" title="Chapter 3. Zend_Auth">
<link rel="chapter" href="zend.cache.html" title="Chapter 4. Zend_Cache">
<link rel="chapter" href="zend.config.html" title="Chapter 5. Zend_Config">
<link rel="chapter" href="zend.console.getopt.html" title="Chapter 6. Zend_Console_Getopt">
<link rel="chapter" href="zend.controller.html" title="Chapter 7. Zend_Controller">
<link rel="chapter" href="zend.currency.html" title="Chapter 8. Zend_Currency">
<link rel="chapter" href="zend.date.html" title="Chapter 9. Zend_Date">
<link rel="chapter" href="zend.db.html" title="Chapter 10. Zend_Db">
<link rel="chapter" href="zend.debug.html" title="Chapter 11. Zend_Debug">
<link rel="chapter" href="zend.dojo.html" title="Chapter 12. Zend_Dojo">
<link rel="chapter" href="zend.dom.html" title="Chapter 13. Zend_Dom">
<link rel="chapter" href="zend.exception.html" title="Chapter 14. Zend_Exception">
<link rel="chapter" href="zend.feed.html" title="Chapter 15. Zend_Feed">
<link rel="chapter" href="zend.filter.html" title="Chapter 16. Zend_Filter">
<link rel="chapter" href="zend.form.html" title="Chapter 17. Zend_Form">
<link rel="chapter" href="zend.gdata.html" title="Chapter 18. Zend_Gdata">
<link rel="chapter" href="zend.http.html" title="Chapter 19. Zend_Http">
<link rel="chapter" href="zend.infocard.html" title="Chapter 20. Zend_InfoCard">
<link rel="chapter" href="zend.json.html" title="Chapter 21. Zend_Json">
<link rel="chapter" href="zend.layout.html" title="Chapter 22. Zend_Layout">
<link rel="chapter" href="zend.ldap.html" title="Chapter 23. Zend_Ldap">
<link rel="chapter" href="zend.loader.html" title="Chapter 24. Zend_Loader">
<link rel="chapter" href="zend.locale.html" title="Chapter 25. Zend_Locale">
<link rel="chapter" href="zend.log.html" title="Chapter 26. Zend_Log">
<link rel="chapter" href="zend.mail.html" title="Chapter 27. Zend_Mail">
<link rel="chapter" href="zend.measure.html" title="Chapter 28. Zend_Measure">
<link rel="chapter" href="zend.memory.html" title="Chapter 29. Zend_Memory">
<link rel="chapter" href="zend.mime.html" title="Chapter 30. Zend_Mime">
<link rel="chapter" href="zend.openid.html" title="Chapter 31. Zend_OpenId">
<link rel="chapter" href="zend.paginator.html" title="Chapter 32. Zend_Paginator">
<link rel="chapter" href="zend.pdf.html" title="Chapter 33. Zend_Pdf">
<link rel="chapter" href="zend.registry.html" title="Chapter 34. Zend_Registry">
<link rel="chapter" href="zend.rest.html" title="Chapter 35. Zend_Rest">
<link rel="chapter" href="zend.search.lucene.html" title="Chapter 36. Zend_Search_Lucene">
<link rel="chapter" href="zend.server.html" title="Chapter 37. Zend_Server">
<link rel="chapter" href="zend.service.html" title="Chapter 38. Zend_Service">
<link rel="chapter" href="zend.session.html" title="Chapter 39. Zend_Session">
<link rel="chapter" href="zend.soap.html" title="Chapter 40. Zend_Soap">
<link rel="chapter" href="zend.test.html" title="Chapter 41. Zend_Test">
<link rel="chapter" href="zend.text.html" title="Chapter 42. Zend_Text">
<link rel="chapter" href="zend.timesync.html" title="Chapter 43. Zend_TimeSync">
<link rel="chapter" href="zend.translate.html" title="Chapter 44. Zend_Translate">
<link rel="chapter" href="zend.uri.html" title="Chapter 45. Zend_Uri">
<link rel="chapter" href="zend.validate.html" title="Chapter 46. Zend_Validate">
<link rel="chapter" href="zend.version.html" title="Chapter 47. Zend_Version">
<link rel="chapter" href="zend.view.html" title="Chapter 48. Zend_View">
<link rel="chapter" href="zend.xmlrpc.html" title="Chapter 49. Zend_XmlRpc">
<link rel="appendix" href="requirements.html" title="Appendix A. Zend Framework Requirements">
<link rel="appendix" href="coding-standard.html" title="Appendix B. Zend Framework Coding Standard for PHP">
<link rel="appendix" href="copyrights.html" title="Appendix C. Copyright Information">
<link rel="index" href="the.index.html" title="Index">
<link rel="subsection" href="zend.auth.adapter.http.html#zend.auth.adapter.http.introduction" title="3.4.1. Introduction">
<link rel="subsection" href="zend.auth.adapter.http.html#zend.auth.adapter.design_overview" title="3.4.2. Design Overview">
<link rel="subsection" href="zend.auth.adapter.http.html#zend.auth.adapter.configuration_options" title="3.4.3. Configuration Options">
<link rel="subsection" href="zend.auth.adapter.http.html#zend.auth.adapter.http.resolvers" title="3.4.4. Resolvers">
<link rel="subsection" href="zend.auth.adapter.http.html#zend.auth.adapter.http.basic_usage" title="3.4.5. Basic Usage">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader"><table width="100%" summary="Navigation header">
<tr><th colspan="3" align="center">3.4. HTTP Authentication Adapter</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="zend.auth.adapter.digest.html">Prev</a> </td>
<th width="60%" align="center">Chapter 3. Zend_Auth</th>
<td width="20%" align="right"> <a accesskey="n" href="zend.auth.adapter.ldap.html">Next</a>
</td>
</tr>
</table></div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="zend.auth.adapter.http"></a>3.4. HTTP Authentication Adapter</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.auth.adapter.http.introduction"></a>3.4.1. Introduction</h3></div></div></div>
<p>
            <code class="code">Zend_Auth_Adapter_Http</code> provides a mostly-compliant implementation of
            <a href="http://tools.ietf.org/html/rfc2617" target="_top">RFC-2617</a>,
            <a href="http://en.wikipedia.org/wiki/Basic_authentication_scheme" target="_top">Basic</a> and
            <a href="http://en.wikipedia.org/wiki/Digest_access_authentication" target="_top">Digest</a> HTTP Authentication.
            Digest authentication is a method of HTTP authentication that improves upon Basic authentication by
            providing a way to authenticate without having to transmit the password in clear text across the network.
        </p>
<p>
            <span class="strong"><strong>Major Features:</strong></span>
            </p>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        Supports both Basic and Digest authentication.
                    </p></li>
<li><p>
                        Issues challenges in all supported schemes, so client can respond with any scheme it supports.
                    </p></li>
<li><p>
                        Supports proxy authentication.
                    </p></li>
<li><p>
                        Includes support for authenticating against text files and provides an interface for
                        authenticating against other sources, such as databases.
                    </p></li>
</ul></div>
<p>
        </p>
<p>
            There are a few notable features of RFC-2617 that are not implemented yet:
            </p>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        Nonce tracking, which would allow for "stale" support, and increased replay attack protection.
                    </p></li>
<li><p>
                        Authentication with integrity checking, or "auth-int".
                    </p></li>
<li><p>
                        Authentication-Info HTTP header.
                    </p></li>
</ul></div>
<p>
        </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.auth.adapter.design_overview"></a>3.4.2. Design Overview</h3></div></div></div>
<p>
            This adapter consists of two sub-components, the HTTP authentication class itself, and the so-called
            "Resolvers." The HTTP authentication class encapsulates the logic for carrying out both Basic and Digest
            authentication. It uses a Resolver to look up a client's identity in some data store (text file by default),
            and retrieve the credentials from the data store. The "resolved" credentials are then compared to the values
            submitted by the client to determine whether authentication is successful.
        </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.auth.adapter.configuration_options"></a>3.4.3. Configuration Options</h3></div></div></div>
<p>
            The <code class="code">Zend_Auth_Adapter_Http</code> class requires a configuration array passed to its constructor.
            There are several configuration options available, and some are required:
            </p>
<div class="table">
<a name="zend.auth.adapter.configuration_options.table"></a><p class="title"><b>Table 3.1. Configuration Options</b></p>
<div class="table-contents"><table summary="Configuration Options" border="1">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>Option Name</th>
<th>Required</th>
<th>Description</th>
</tr></thead>
<tbody>
<tr>
<td><code class="code">accept_schemes</code></td>
<td>Yes</td>
<td>
                                Determines which authentication schemes the adapter will accept from the client. Must be
                                a space-separated list containing <code class="code">'basic'</code> and/or <code class="code">'digest'</code>.
                            </td>
</tr>
<tr>
<td><code class="code">realm</code></td>
<td>Yes</td>
<td>
                                Sets the authentication realm; usernames should be unique within a given realm.
                            </td>
</tr>
<tr>
<td><code class="code">digest_domains</code></td>
<td>Yes, when <code class="code">'accept_schemes'</code> contains <code class="code">'digest'</code>
</td>
<td>
                                Space-separated list of URIs for which the same authentication information is valid. The
                                URIs need not all point to the same server.
                            </td>
</tr>
<tr>
<td><code class="code">nonce_timeout</code></td>
<td>Yes, when <code class="code">'accept_schemes'</code> contains <code class="code">'digest'</code>
</td>
<td>
                                Sets the number of seconds for which the nonce is valid. See notes below.
                            </td>
</tr>
<tr>
<td><code class="code">proxy_auth</code></td>
<td>No</td>
<td>
                                Disabled by default. Enable to perform Proxy authentication, instead of normal origin
                                server authentication.
                            </td>
</tr>
</tbody>
</table></div>
</div>
<p><br class="table-break">
        </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
                The current implementation of the <code class="code">nonce_timeout</code> has some interesting side effects. This
                setting is supposed to determine the valid lifetime of a given nonce, or effectively how long a client's
                authentication information is accepted. Currently, if it's set to 3600 (for example), it will cause the
                adapter to prompt the client for new credentials every hour, on the hour. This will be resolved in a
                future release, once nonce tracking and stale support are implemented.
            </p></td></tr>
</table></div>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.auth.adapter.http.resolvers"></a>3.4.4. Resolvers</h3></div></div></div>
<p>
            The resolver's job is to take a username and realm, and return some kind of credential value. Basic
            authentication expects to receive the Base64 encoded version of the user's password. Digest authentication
            expects to receive a hash of the user's username, the realm, and their password (each separated by colons).
            Currently, the only supported hash algorithm is MD5.
        </p>
<p>
            <code class="code">Zend_Auth_Adapter_Http</code> relies on objects implementing
            <code class="code">Zend_Auth_Adapter_Http_Resolver_Interface</code>. A text file resolver class is included with this
            adapter, but any other kind of resolver can be created simply by implementing the resolver interface.
        </p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.auth.adapter.http.resolvers.file"></a>3.4.4.1. File Resolver</h4></div></div></div>
<p>
                The file resolver is a very simple class. It has a single property specifying a filename, which can also
                be passed to the constructor. Its <code class="code">resolve()</code> method walks through the text file, searching
                for a line with a matching username and realm. The text file format similar to Apache htpasswd files:
                </p>
<pre class="programlisting">&lt;username&gt;:&lt;realm&gt;:&lt;credentials&gt;\n</pre>
<p>
                Each line consists of three fields - username, realm, and credentials - each separated by a colon. The
                credentials field is opaque to the file resolver; it simply returns that value as-is to the caller.
                Therefore, this same file format serves both Basic and Digest authentication. In Basic authentication,
                the credentials field should be the Base64 encoding of the user's password. In Digest authentication, it
                should be the MD5 hash described above.
            </p>
<p>
                There are two equally easy ways to create a File resolver:
                </p>
<pre class="programlisting">&lt;?php
$path     = 'files/passwd.txt';
$resolver = new Zend_Auth_Adapter_Http_Resolver_File($path);
                </pre>
<p>
                or
                </p>
<pre class="programlisting">&lt;?php
$path     = 'files/passwd.txt';
$resolver = new Zend_Auth_Adapter_Http_Resolver_File();
$resolver-&gt;setFile($path);
                </pre>
<p>
                If the given path is empty or not readable, an exception is thrown.
            </p>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.auth.adapter.http.basic_usage"></a>3.4.5. Basic Usage</h3></div></div></div>
<p>
            First, set up an array with the required configuration values:
            </p>
<pre class="programlisting">&lt;?php
$config = array(
    'accept_schemes' =&gt; 'basic digest',
    'realm'          =&gt; 'My Web Site',
    'digest_domains' =&gt; '/members_only /my_account',
    'nonce_timeout'  =&gt; 3600,
);
            </pre>
<p>
            This array will cause the adapter to accept either Basic or Digest authentication, and will require
            authenticated access to all the areas of the site under <code class="code">/members_only</code> and
            <code class="code">/my_account</code>. The realm value is usually displayed by the browser in the password dialog box.
            The <code class="code">nonce_timeout</code>, of course, behaves as described above.
        </p>
<p>
            Next, create the Zend_Auth_Adapter_Http object:
            </p>
<pre class="programlisting">&lt;?php
require_once 'Zend/Auth/Adapter/Http.php';
$adapter = new Zend_Auth_Adapter_Http($config);
            </pre>
<p>
        </p>
<p>
            Since we're supporting both Basic and Digest authentication, we need two different resolver objects. Note
            that this could just as easily be two different classes:
            </p>
<pre class="programlisting">&lt;?php
require_once 'Zend/Auth/Adapter/Http/Resolver/File.php';

$basicResolver = new Zend_Auth_Adapter_Http_Resolver_File();
$basicResolver-&gt;setFile('files/basicPasswd.txt');

$digestResolver = new Zend_Auth_Adapter_Http_Resolver_File();
$digestResolver-&gt;setFile('files/digestPasswd.txt');

$adapter-&gt;setBasicResolver($basicResolver);
$adapter-&gt;setDigestResolver($digestResolver);
            </pre>
<p>
        </p>
<p>
            Finally, we perform the authentication. The adapter needs a reference to both the Request and Response
            objects in order to do its job:
            </p>
<pre class="programlisting">&lt;?php
assert($request instanceof Zend_Controller_Request_Http);
assert($response instanceof Zend_Controller_Response_Http);

$adapter-&gt;setRequest($request);
$adapter-&gt;setResponse($response);

$result = $adapter-&gt;authenticate();
if (!$result-&gt;isValid()) {
    // Bad userame/password, or canceled password prompt
}
            </pre>
<p>
        </p>
</div>
</div>
<div class="navfooter"><table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="zend.auth.adapter.digest.html">Prev</a> </td>
<td width="20%" align="center"><a accesskey="u" href="zend.auth.html">Up</a></td>
<td width="40%" align="right"> <a accesskey="n" href="zend.auth.adapter.ldap.html">Next</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">3.3. Digest Authentication </td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top"> 3.5. LDAP Authentication</td>
</tr>
</table></div>
<div class="revinfo"></div>
</body>
</html>
